/*
 * @Author: WangShuai 1830773767@qq.com
 * @Date: 2025-05-07 21:09:45
 * @LastEditors: WangShuai 1830773767@qq.com
 * @LastEditTime: 2025-05-11 10:44:26
 * @FilePath: \Webgl-basic\src\6.绘制正三角形.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import {
    initShader,
    createBuffer,
} from '../lib/index'
import {
    mat4
} from 'gl-matrix';
import * as dat from 'dat.gui'
const canvas = document.querySelector('canvas')
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
//获取webgl上下文
const gl = canvas.getContext('webgl')
//定义点顶点着色器(字符串)
const vs_shader = /*glsl*/ `
  // 指定浮点数精度为中等精度  
  precision mediump float;//glsl语法每一行后面都要加上分号,每一行后面都要加上分号
  attribute vec3 a_Position;
  uniform mat4 u_ViewMatrix;
  uniform mat4 u_ProjMatrix;
  //glsl语法中,必须有一个入口函数main shaderToy里面叫mainImage cesuim里面可能叫czm_Main
  void main(){
    //gl_Position 是最后输出的坐标值,Vect4是四维向量,具有四个分量,每一个分量都是float
    // gl_Position= vec4(a_Position,1.0);
    gl_Position= u_ProjMatrix *u_ViewMatrix* vec4(a_Position,1.0);

  }`
//片元着色器
const fs_shader = /*glsl*/ `
precision mediump float;
void main(){
    //gl_FragColor是最后输出的像素颜色,是一个四维的数据
    gl_FragColor = vec4(1.0,0.0,0.0,1.0);            
}`
//编译着色器,生成程序对象  操作手，专门负责javaScript和shader着色器的通讯
const program = initShader(gl, vs_shader, fs_shader)
gl.program = program;


//视点位置
const viewObj = {
    eyeX: 0,
    eyeY: 0,
    eyeZ: 1,
    lookAtX: 0,
    lookAtY: 0,
    lookAtZ: 0,
    fov: 40,
    near: 0.2,
    far: 1,
}
const renderView = () => {
    renderProMatrix()
    renderViewMatrix()
    const n = createCube();
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);
    //如果使用缓冲区的话,使用drawElemtnts来绘制
    gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);
}

const renderProMatrix = () => {
    const u_ProjMatrix = gl.getUniformLocation(program, 'u_ProjMatrix')
    //创建正射投影矩阵
    let projMatrix = mat4.create();
    // console.log("projMatrix1", projMatrix);
    mat4.identity(projMatrix);
    //使用正射投影矩阵 参数 左右上下近远六个面的距离
    // projMatrix = mat4.orthoNO(projMatrix,-1,1,-1,1,viewObj.near,viewObj.far)
    //使用透视投影矩阵
    projMatrix = mat4.perspectiveNO(projMatrix, viewObj.fov, window.innerWidth / window.innerHeight, viewObj.near, viewObj.far)
    // console.log("projMatrix2", projMatrix);
    gl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix);

}
const renderViewMatrix = () => {
    const u_ViewMatrix = gl.getUniformLocation(program, 'u_ViewMatrix')
    //创建视图矩阵
    let viewMatrix = mat4.create();
    // console.log("viewMatrix1", viewMatrix);
    mat4.identity(viewMatrix);
    viewMatrix = mat4.lookAt(viewMatrix, [viewObj.eyeX, viewObj.eyeY, viewObj.eyeZ], [viewObj.lookAtX, viewObj.lookAtY, viewObj.lookAtZ], [0, 1, 0])
    // console.log("viewMatrix2", viewMatrix);
    gl.uniformMatrix4fv(u_ViewMatrix, false, viewMatrix);
}
//创建正方体函数
const createCube = () => {
    //正方体顶点
    const vertices = [
        // 顶点坐标            // 颜色
        -0.5, -0.5, -0.5, // 0: 左下后，红色
        0.5, -0.5, -0.5, // 1: 右下后，绿色
        0.5, 0.5, -0.5, // 2: 右上后，蓝色
        -0.5, 0.5, -0.5, // 3: 左上后，黄色
        -0.5, -0.5, 0.5, // 4: 左下前，洋红
        0.5, -0.5, 0.5, // 5: 右下前，青色
        0.5, 0.5, 0.5, // 6: 右上前，灰色
        -0.5, 0.5, 0.5, // 7: 左上前，黑色
    ];

    //定义每个点索引
    let indices = [
        0, 1, 2, 2, 3, 0, // 后面
        4, 5, 6, 6, 7, 4, // 前面
        0, 3, 7, 7, 4, 0, // 左侧
        1, 2, 6, 6, 5, 1, // 右侧
        0, 1, 5, 5, 4, 0, // 下面
        2, 3, 7, 7, 6, 2 // 上面
    ];
    //必须要Uint8Array
    indices = new Uint8Array(indices)
    createBuffer(gl, vertices, 'a_Position', {
        size: 3
    })
    //创建索引缓冲区  使用索引缓冲区后,就不会再按照原本的下标进行取值,而是使用索引中的value来对vertices进行取值
    let indexBuffer = gl.createBuffer();
    //创建绑定索引缓冲区
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
    gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
    return indices.length;
}

renderView()














const gui = new dat.GUI();
const projFolder = gui.addFolder('proj');
projFolder.add(viewObj, 'near', -1, 1, 0.01).onChange(renderView)
projFolder.add(viewObj, 'far', -1, 2, 0.01).onChange(renderView)
projFolder.add(viewObj, 'fov', 0, 90, 0.1).onChange(renderView)


const eyeFolder = gui.addFolder('eyePosition');
eyeFolder.add(viewObj, 'eyeX', -1, 1, 0.01).onChange(renderView)
eyeFolder.add(viewObj, 'eyeY', -1, 1, 0.01).onChange(renderView)
eyeFolder.add(viewObj, 'eyeZ', -1, 5, 0.01).onChange(renderView)

const lookAtFolder = gui.addFolder('lookPostion');
lookAtFolder.add(viewObj, 'lookAtX', 0, 1, 0.01).onChange(renderView)
lookAtFolder.add(viewObj, 'lookAtY', 0, 1, 0.01).onChange(renderView)
lookAtFolder.add(viewObj, 'lookAtZ', 0, 1, 0.01).onChange(renderView)